<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>课堂小组加分工具</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    
    <!-- 配置Tailwind自定义颜色和字体 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#4F46E5',
                        secondary: '#10B981',
                        accent: '#F59E0B',
                        danger: '#EF4444',
                        light: '#F3F4F6',
                        dark: '#1F2937'
                    },
                    fontFamily: {
                        comic: ['Comic Sans MS', 'cursive', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .smooth-enter {
                animation: smooth-enter 0.5s ease-out;
            }
            .score-change-up {
                animation: score-change-up 0.5s ease-out;
            }
            .score-change-down {
                animation: score-change-down 0.5s ease-out;
            }
            .pulse-selection {
                animation: pulse-selection 1.5s infinite;
            }
            .rank-badge-1 {
                background: linear-gradient(135deg, #FFD700 0%, #FFC107 100%);
                box-shadow: 0 2px 8px rgba(255, 215, 0, 0.4);
                transform: rotate(-3deg);
            }
            .rank-badge-2 {
                background: linear-gradient(135deg, #E0E0E0 0%, #BDBDBD 100%);
                box-shadow: 0 2px 8px rgba(224, 224, 224, 0.4);
                transform: rotate(2deg);
            }
            .rank-badge-3 {
                background: linear-gradient(135deg, #CD7F32 0%, #B87333 100%);
                box-shadow: 0 2px 8px rgba(205, 127, 50, 0.4);
                transform: rotate(-2deg);
            }
            .rank-badge-other {
                background: linear-gradient(135deg, #6B7280 0%, #4B5563 100%);
                box-shadow: 0 2px 8px rgba(107, 114, 128, 0.4);
            }
            .score-highlight {
                text-shadow: 0 3px 6px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.1);
            }
            .score-zero {
                text-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
            }
        }
        
        /* 平滑进入动画 */
        @keyframes smooth-enter {
            0% { transform: translateY(20px); opacity: 0; }
            100% { transform: translateY(0); opacity: 1; }
        }
        
        /* 分数增加动画 - 增强视觉效果 */
        @keyframes score-change-up {
            0% { transform: scale(1); }
            50% { transform: scale(1.2); color: #10B981; text-shadow: 0 6px 12px rgba(16, 185, 129, 0.4); }
            100% { transform: scale(1); }
        }
        
        /* 分数减少动画 - 增强视觉效果 */
        @keyframes score-change-down {
            0% { transform: scale(1); }
            50% { transform: scale(0.9); color: #EF4444; text-shadow: 0 6px 12px rgba(239, 68, 68, 0.4); }
            100% { transform: scale(1); }
        }
        
        /* 选中状态动画 */
        @keyframes pulse-selection {
            0% { box-shadow: 0 0 0 0 rgba(79, 70, 229, 0.4); }
            70% { box-shadow: 0 0 0 8px rgba(79, 70, 229, 0); }
            100% { box-shadow: 0 0 0 0 rgba(79, 70, 229, 0); }
        }
        
        /* 小组卡片容器 */
        #groups-container {
            display: grid;
            gap: 1.5rem;
            transition: all 0.3s ease-out;
        }
        
        /* 小组卡片 - 增加内边距以容纳更大的分数 */
        .group-card {
            transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
            padding: 0.5rem 0.5rem 1.25rem;
            min-height: 240px;
            display: flex;
            flex-direction: column;
        }
    </style>
</head>
<body class="bg-gradient-to-br from-blue-50 to-purple-50 min-h-screen font-comic text-dark">
    <!-- 页面标题 -->
    <header class="bg-primary text-white p-4 shadow-lg">
        <div class="container mx-auto flex justify-between items-center">
            <h1 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold flex items-center">
                <i class="fa fa-star mr-3 text-accent animate-pulse"></i>
                课堂小组加分工具
            </h1>
            <div class="flex gap-2">
                <button id="sound-toggle" class="bg-white/20 hover:bg-white/30 p-2 rounded-full transition-all">
                    <i class="fa fa-volume-up text-xl"></i>
                </button>
                <button id="settings-btn" class="bg-white/20 hover:bg-white/30 p-2 rounded-full transition-all">
                    <i class="fa fa-cog text-xl"></i>
                </button>
            </div>
        </div>
    </header>

    <main class="container mx-auto p-4">
        <!-- 控制区域 -->
        <div class="bg-white rounded-xl shadow-md p-4 mb-6 flex flex-wrap gap-3 justify-between items-center">
            <div class="flex flex-wrap gap-3">
                <button id="add-group-btn" class="bg-secondary hover:bg-secondary/80 text-white px-4 py-2 rounded-lg flex items-center transition-all transform hover:scale-105">
                    <i class="fa fa-plus-circle mr-2"></i> 添加小组
                </button>
                <button id="batch-add-btn" class="bg-accent hover:bg-accent/80 text-white px-4 py-2 rounded-lg flex items-center transition-all transform hover:scale-105">
                    <i class="fa fa-users mr-2"></i> 批量添加
                </button>
                <button id="reset-all-btn" class="bg-amber-500 hover:bg-amber-600 text-white px-4 py-2 rounded-lg flex items-center transition-all transform hover:scale-105">
                    <i class="fa fa-refresh mr-2"></i> 重置分数
                </button>
            </div>
            
            <!-- 批量操作区域 -->
            <div class="flex flex-wrap gap-3" id="batch-operations">
                <button id="select-all-btn" class="bg-primary/10 hover:bg-primary/20 text-primary px-4 py-2 rounded-lg flex items-center transition-all" disabled>
                    <i class="fa fa-check-square-o mr-2"></i> 全选
                </button>
                <button id="deselect-all-btn" class="bg-primary/10 hover:bg-primary/20 text-primary px-4 py-2 rounded-lg flex items-center transition-all" disabled>
                    <i class="fa fa-square-o mr-2"></i> 取消选择
                </button>
                <button id="delete-selected-btn" class="bg-danger/10 hover:bg-danger/20 text-danger px-4 py-2 rounded-lg flex items-center transition-all" disabled>
                    <i class="fa fa-trash mr-2"></i> 删除选中
                </button>
                <button id="clear-all-groups-btn" class="bg-gray-700 hover:bg-gray-800 text-white px-4 py-2 rounded-lg flex items-center transition-all" disabled>
                    <i class="fa fa-trash-o mr-2"></i> 清空所有
                </button>
            </div>
            
            <div class="flex flex-wrap gap-3">
                <div class="relative">
                    <select id="score-step" class="bg-light border-0 pl-4 pr-10 py-2 rounded-lg appearance-none focus:ring-2 focus:ring-primary">
                        <option value="1">每次加1分</option>
                        <option value="2">每次加2分</option>
                        <option value="3">每次加3分</option>
                        <option value="5">每次加5分</option>
                        <option value="10">每次加10分</option>
                    </select>
                    <i class="fa fa-chevron-down absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 pointer-events-none"></i>
                </div>
                
                <button id="save-class-btn" class="bg-primary hover:bg-primary/80 text-white px-4 py-2 rounded-lg flex items-center transition-all transform hover:scale-105">
                    <i class="fa fa-save mr-2"></i> 保存班级
                </button>
                <button id="load-class-btn" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg flex items-center transition-all transform hover:scale-105">
                    <i class="fa fa-folder-open mr-2"></i> 加载班级
                </button>
            </div>
        </div>
        
        <!-- 班级选择区域 (默认隐藏) -->
        <div id="class-selector" class="hidden bg-white rounded-xl shadow-md p-4 mb-6">
            <h2 class="text-xl font-bold mb-3 flex items-center">
                <i class="fa fa-folder-open text-primary mr-2"></i> 选择已保存的班级
            </h2>
            <div id="saved-classes" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
                <!-- 保存的班级将在这里显示 -->
                <div class="text-gray-500 italic text-center py-4">暂无保存的班级数据</div>
            </div>
        </div>
        
        <!-- 小组卡片容器 -->
        <div id="groups-container" class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4">
            <!-- 小组卡片将通过JavaScript动态生成 -->
            <div class="col-span-full text-center py-10 text-gray-500 italic">
                <i class="fa fa-users text-5xl mb-3 opacity-30"></i>
                <p>点击"添加小组"或"批量添加"来创建小组</p>
            </div>
        </div>
    </main>

    <!-- 批量添加小组模态框 -->
    <div id="batch-modal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
        <div class="bg-white rounded-xl shadow-xl p-6 w-full max-w-md smooth-enter">
            <h3 class="text-xl font-bold mb-4 flex items-center">
                <i class="fa fa-users text-accent mr-2"></i> 批量添加小组
            </h3>
            <div class="space-y-4">
                <div>
                    <label class="block text-sm font-medium mb-1">小组数量</label>
                    <input type="number" id="batch-count" min="1" max="20" value="4" 
                        class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">
                </div>
                <div>
                    <label class="block text-sm font-medium mb-1">小组名称前缀</label>
                    <input type="text" id="batch-prefix" value="第" 
                        class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">
                </div>
                <div>
                    <label class="block text-sm font-medium mb-1">小组名称后缀</label>
                    <input type="text" id="batch-suffix" value="组" 
                        class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">
                </div>
                <div class="pt-2 flex gap-3">
                    <button id="cancel-batch" class="flex-1 bg-gray-200 hover:bg-gray-300 px-4 py-2 rounded-lg transition-colors">
                        取消
                    </button>
                    <button id="confirm-batch" class="flex-1 bg-accent hover:bg-accent/80 text-white px-4 py-2 rounded-lg transition-colors">
                        确认添加
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- 添加/编辑小组模态框 -->
    <div id="group-modal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
        <div class="bg-white rounded-xl shadow-xl p-6 w-full max-w-md smooth-enter">
            <h3 id="modal-title" class="text-xl font-bold mb-4 flex items-center">
                <i class="fa fa-plus-circle text-secondary mr-2"></i> 添加小组
            </h3>
            <div class="space-y-4">
                <div>
                    <label class="block text-sm font-medium mb-1">小组名称</label>
                    <input type="text" id="group-name" placeholder="输入小组名称" 
                        class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">
                </div>
                <div>
                    <label class="block text-sm font-medium mb-1">小组颜色</label>
                    <div class="grid grid-cols-6 gap-2">
                        <div class="color-option w-10 h-10 rounded-full bg-red-400 cursor-pointer hover:scale-110 transition-transform" data-color="bg-red-400"></div>
                        <div class="color-option w-10 h-10 rounded-full bg-blue-400 cursor-pointer hover:scale-110 transition-transform" data-color="bg-blue-400"></div>
                        <div class="color-option w-10 h-10 rounded-full bg-green-400 cursor-pointer hover:scale-110 transition-transform" data-color="bg-green-400"></div>
                        <div class="color-option w-10 h-10 rounded-full bg-yellow-400 cursor-pointer hover:scale-110 transition-transform" data-color="bg-yellow-400"></div>
                        <div class="color-option w-10 h-10 rounded-full bg-purple-400 cursor-pointer hover:scale-110 transition-transform" data-color="bg-purple-400"></div>
                        <div class="color-option w-10 h-10 rounded-full bg-pink-400 cursor-pointer hover:scale-110 transition-transform" data-color="bg-pink-400"></div>
                    </div>
                    <input type="hidden" id="group-color" value="bg-blue-400">
                </div>
                <div class="pt-2 flex gap-3">
                    <button id="cancel-group" class="flex-1 bg-gray-200 hover:bg-gray-300 px-4 py-2 rounded-lg transition-colors">
                        取消
                    </button>
                    <button id="confirm-group" class="flex-1 bg-secondary hover:bg-secondary/80 text-white px-4 py-2 rounded-lg transition-colors">
                        确认添加
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- 保存班级模态框 -->
    <div id="save-class-modal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
        <div class="bg-white rounded-xl shadow-xl p-6 w-full max-w-md smooth-enter">
            <h3 class="text-xl font-bold mb-4 flex items-center">
                <i class="fa fa-save text-primary mr-2"></i> 保存班级
            </h3>
            <div class="space-y-4">
                <div>
                    <label class="block text-sm font-medium mb-1">班级名称</label>
                    <input type="text" id="class-name" placeholder="例如：三年级二班" 
                        class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">
                </div>
                <div class="text-sm text-gray-500">
                    <i class="fa fa-info-circle mr-1"></i> 班级数据将保存在本地，下次可以直接加载使用
                </div>
                <div class="pt-2 flex gap-3">
                    <button id="cancel-save-class" class="flex-1 bg-gray-200 hover:bg-gray-300 px-4 py-2 rounded-lg transition-colors">
                        取消
                    </button>
                    <button id="confirm-save-class" class="flex-1 bg-primary hover:bg-primary/80 text-white px-4 py-2 rounded-lg transition-colors">
                        确认保存
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- 设置模态框 -->
    <div id="settings-modal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
        <div class="bg-white rounded-xl shadow-xl p-6 w-full max-w-md smooth-enter">
            <h3 class="text-xl font-bold mb-4 flex items-center">
                <i class="fa fa-cog text-primary mr-2"></i> 系统设置
            </h3>
            <div class="space-y-4">
                <div class="flex items-center justify-between">
                    <label class="text-sm font-medium">音效开关</label>
                    <label class="relative inline-flex items-center cursor-pointer">
                        <input type="checkbox" id="sound-enabled" checked class="sr-only peer">
                        <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-primary rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary"></div>
                    </label>
                </div>
                
                <div class="flex items-center justify-between">
                    <label class="text-sm font-medium">动画效果</label>
                    <label class="relative inline-flex items-center cursor-pointer">
                        <input type="checkbox" id="animation-enabled" checked class="sr-only peer">
                        <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-primary rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary"></div>
                    </label>
                </div>
                
                <div class="pt-2 border-t border-gray-200">
                    <button id="clear-all-data" class="w-full bg-danger hover:bg-danger/80 text-white px-4 py-2 rounded-lg transition-colors flex items-center justify-center">
                        <i class="fa fa-trash mr-2"></i> 清除所有保存数据
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- 音效元素 -->
    <audio id="add-sound" preload="auto">
        <source src="https://assets.mixkit.co/sfx/preview/mixkit-achievement-bell-600.mp3" type="audio/mpeg">
    </audio>
    <audio id="remove-sound" preload="auto">
        <source src="https://assets.mixkit.co/sfx/preview/mixkit-wrong-answer-fail-notification-946.mp3" type="audio/mpeg">
    </audio>
    <audio id="success-sound" preload="auto">
        <source src="https://assets.mixkit.co/sfx/preview/mixkit-correct-answer-tone-2870.mp3" type="audio/mpeg">
    
    <audio id="select-sound" preload="auto">
        <source src="https://assets.mixkit.co/sfx/preview/mixkit-select-click-1109.mp3" type="audio/mpeg">
    </audio>
    <audio id="confirm-sound" preload="auto">
        <source src="https://assets.mixkit.co/sfx/preview/mixkit-software-interface-start-2574.mp3" type="audio/mpeg">
    
    <audio id="cancel-sound" preload="auto">
        <source src="https://assets.mixkit.co/sfx/preview/mixkit-interface-hint-notification-911.mp3" type="audio/mpeg">
    

    <script>
        // 全局变量
        let groups = [];
        let currentEditingGroupId = null;
        let soundEnabled = true;
        let animationEnabled = true;
        let groupIdCounter = 0; // 用于生成唯一ID的计数器
        
        // DOM 元素
        const groupsContainer = document.getElementById('groups-container');
        const groupModal = document.getElementById('group-modal');
        const batchModal = document.getElementById('batch-modal');
        const saveClassModal = document.getElementById('save-class-modal');
        const settingsModal = document.getElementById('settings-modal');
        const classSelector = document.getElementById('class-selector');
        const savedClassesContainer = document.getElementById('saved-classes');
        
        // 批量操作按钮
        const selectAllBtn = document.getElementById('select-all-btn');
        const deselectAllBtn = document.getElementById('deselect-all-btn');
        const deleteSelectedBtn = document.getElementById('delete-selected-btn');
        const clearAllGroupsBtn = document.getElementById('clear-all-groups-btn');
        
        // 音效元素
        const addSound = document.getElementById('add-sound');
        const removeSound = document.getElementById('remove-sound');
        const successSound = document.getElementById('success-sound');
        const selectSound = document.getElementById('select-sound');
        const confirmSound = document.getElementById('confirm-sound');
        const cancelSound = document.getElementById('cancel-sound');
        
        // 生成唯一小组ID
        function generateUniqueId() {
            // 结合时间戳和计数器确保ID唯一
            const timestamp = Date.now().toString(36);
            const counter = (groupIdCounter++).toString(36);
            return `${timestamp}-${counter}`;
        }
        
        // 初始化
        function init() {
            loadSettings();
            renderGroups();
            loadSavedClasses();
            updateBatchOperationButtons();
            
            // 事件监听
            document.getElementById('add-group-btn').addEventListener('click', openAddGroupModal);
            document.getElementById('batch-add-btn').addEventListener('click', openBatchAddModal);
            document.getElementById('confirm-batch').addEventListener('click', handleBatchAdd);
            document.getElementById('cancel-batch').addEventListener('click', () => {
                closeBatchModal();
                playSound(cancelSound);
            });
            document.getElementById('cancel-group').addEventListener('click', () => {
                closeGroupModal();
                playSound(cancelSound);
            });
            document.getElementById('confirm-group').addEventListener('click', handleAddOrEditGroup);
            document.getElementById('reset-all-btn').addEventListener('click', resetAllScores);
            document.getElementById('save-class-btn').addEventListener('click', openSaveClassModal);
            document.getElementById('cancel-save-class').addEventListener('click', () => {
                closeSaveClassModal();
                playSound(cancelSound);
            });
            document.getElementById('confirm-save-class').addEventListener('click', saveCurrentClass);
            document.getElementById('load-class-btn').addEventListener('click', toggleClassSelector);
            document.getElementById('settings-btn').addEventListener('click', openSettingsModal);
            document.getElementById('sound-toggle').addEventListener('click', toggleSound);
            document.getElementById('sound-enabled').addEventListener('change', updateSoundSetting);
            document.getElementById('animation-enabled').addEventListener('change', updateAnimationSetting);
            document.getElementById('clear-all-data').addEventListener('click', clearAllData);
            
            // 批量操作事件监听
            selectAllBtn.addEventListener('click', selectAllGroups);
            deselectAllBtn.addEventListener('click', deselectAllGroups);
            deleteSelectedBtn.addEventListener('click', deleteSelectedGroups);
            clearAllGroupsBtn.addEventListener('click', clearAllGroups);
            
            // 颜色选择
            document.querySelectorAll('.color-option').forEach(option => {
                option.addEventListener('click', () => {
                    // 移除其他选中状态
                    document.querySelectorAll('.color-option').forEach(opt => {
                        opt.classList.remove('ring-2', 'ring-primary', 'ring-offset-2');
                    });
                    // 添加当前选中状态
                    option.classList.add('ring-2', 'ring-primary', 'ring-offset-2');
                    // 保存选择的颜色
                    document.getElementById('group-color').value = option.dataset.color;
                    playSound(selectSound);
                });
            });
            
            // 默认选中第一个颜色
            document.querySelector('.color-option').click();
        }
        
        // 播放音效
        function playSound(sound) {
            if (soundEnabled) {
                // 停止当前播放并重新开始
                sound.pause();
                sound.currentTime = 0;
                sound.play().catch(e => console.log('播放音效失败:', e));
            }
        }
        
        // 切换音效开关
        function toggleSound() {
            soundEnabled = !soundEnabled;
            updateSoundUI();
            saveSettings();
            playSound(selectSound);
        }
        
        // 更新音效UI
        function updateSoundUI() {
            const soundIcon = document.querySelector('#sound-toggle i');
            if (soundEnabled) {
                soundIcon.className = 'fa fa-volume-up text-xl';
            } else {
                soundIcon.className = 'fa fa-volume-off text-xl';
            }
            document.getElementById('sound-enabled').checked = soundEnabled;
        }
        
        // 更新音效设置
        function updateSoundSetting() {
            soundEnabled = document.getElementById('sound-enabled').checked;
            updateSoundUI();
            saveSettings();
            playSound(selectSound);
        }
        
        // 更新动画设置
        function updateAnimationSetting() {
            animationEnabled = document.getElementById('animation-enabled').checked;
            saveSettings();
            playSound(selectSound);
        }
        
        // 保存设置
        function saveSettings() {
            const settings = {
                soundEnabled,
                animationEnabled
            };
            localStorage.setItem('scoreToolSettings', JSON.stringify(settings));
        }
        
        // 加载设置
        function loadSettings() {
            const savedSettings = localStorage.getItem('scoreToolSettings');
            if (savedSettings) {
                const settings = JSON.parse(savedSettings);
                soundEnabled = settings.soundEnabled !== undefined ? settings.soundEnabled : true;
                animationEnabled = settings.animationEnabled !== undefined ? settings.animationEnabled : true;
                document.getElementById('sound-enabled').checked = soundEnabled;
                document.getElementById('animation-enabled').checked = animationEnabled;
                updateSoundUI();
            }
        }
        
        // 打开添加小组模态框
        function openAddGroupModal() {
            currentEditingGroupId = null;
            document.getElementById('modal-title').innerHTML = '<i class="fa fa-plus-circle text-secondary mr-2"></i> 添加小组';
            document.getElementById('group-name').value = '';
            document.getElementById('confirm-group').textContent = '确认添加';
            groupModal.classList.remove('hidden');
            document.getElementById('group-name').focus();
            playSound(selectSound);
        }
        
        // 打开编辑小组模态框
        function openEditGroupModal(groupId) {
            const group = groups.find(g => g.id === groupId);
            if (group) {
                currentEditingGroupId = groupId;
                document.getElementById('modal-title').innerHTML = '<i class="fa fa-pencil text-secondary mr-2"></i> 编辑小组';
                document.getElementById('group-name').value = group.name;
                document.getElementById('group-color').value = group.color;
                
                // 选中对应的颜色
                document.querySelectorAll('.color-option').forEach(option => {
                    if (option.dataset.color === group.color) {
                        option.click();
                    }
                });
                
                document.getElementById('confirm-group').textContent = '确认修改';
                groupModal.classList.remove('hidden');
                document.getElementById('group-name').focus();
                playSound(selectSound);
            }
        }
        
        // 关闭小组模态框
        function closeGroupModal() {
            groupModal.classList.add('hidden');
        }
        
        // 打开批量添加模态框
        function openBatchAddModal() {
            batchModal.classList.remove('hidden');
            document.getElementById('batch-count').focus();
            playSound(selectSound);
        }
        
        // 关闭批量添加模态框
        function closeBatchModal() {
            batchModal.classList.add('hidden');
        }
        
        // 处理批量添加
        function handleBatchAdd() {
            const count = parseInt(document.getElementById('batch-count').value) || 0;
            const prefix = document.getElementById('batch-prefix').value;
            const suffix = document.getElementById('batch-suffix').value;
            
            if (count < 1 || count > 20) {
                alert('请输入1-20之间的数字');
                playSound(cancelSound);
                return;
            }
            
            const colors = [
                'bg-red-400', 'bg-blue-400', 'bg-green-400', 
                'bg-yellow-400', 'bg-purple-400', 'bg-pink-400'
            ];
            
            for (let i = 1; i <= count; i++) {
                const groupName = `${prefix}${i}${suffix}`;
                const color = colors[i % colors.length];
                
                addGroup(groupName, color);
            }
            
            closeBatchModal();
            playSound(successSound);
        }
        
        // 处理添加或编辑小组
        function handleAddOrEditGroup() {
            const groupName = document.getElementById('group-name').value.trim();
            const groupColor = document.getElementById('group-color').value;
            
            if (!groupName) {
                alert('请输入小组名称');
                playSound(cancelSound);
                return;
            }
            
            if (currentEditingGroupId === null) {
                // 添加新小组
                addGroup(groupName, groupColor);
                playSound(successSound);
            } else {
                // 编辑现有小组
                editGroup(currentEditingGroupId, groupName, groupColor);
                playSound(successSound);
            }
            
            closeGroupModal();
        }
        
        // 添加小组
        function addGroup(name, color) {
            const newGroup = {
                id: generateUniqueId(),
                name,
                color,
                score: 0,
                selected: false // 新增选中状态属性
            };
            
            groups.push(newGroup);
            renderGroups();
            updateBatchOperationButtons();
        }
        
        // 编辑小组
        function editGroup(groupId, newName, newColor) {
            const index = groups.findIndex(g => g.id === groupId);
            if (index !== -1) {
                groups[index].name = newName;
                groups[index].color = newColor;
                renderGroups();
            }
        }
        
        // 删除单个小组
        function deleteGroup(groupId) {
            if (confirm('确定要删除这个小组吗？')) {
                // 从数组中移除小组
                const initialLength = groups.length;
                groups = groups.filter(g => g.id !== groupId);
                
                // 为删除的元素添加淡出动画
                const deletedCard = document.querySelector(`.group-card[data-id="${groupId}"]`);
                if (deletedCard && animationEnabled) {
                    deletedCard.style.opacity = '0';
                    deletedCard.style.transform = 'translateY(20px)';
                    deletedCard.style.height = `${deletedCard.offsetHeight}px`;
                    
                    // 等待动画完成后再重新渲染
                    setTimeout(() => {
                        renderGroups();
                        updateBatchOperationButtons();
                    }, 300);
                } else {
                    renderGroups();
                    updateBatchOperationButtons();
                }
                
                playSound(removeSound);
            }
        }
        
        // 切换小组选中状态
        function toggleGroupSelection(groupId) {
            const index = groups.findIndex(g => g.id === groupId);
            if (index !== -1) {
                groups[index].selected = !groups[index].selected;
                renderGroups();
                updateBatchOperationButtons();
                playSound(selectSound);
            }
        }
        
        // 全选小组
        function selectAllGroups() {
            groups.forEach(group => {
                group.selected = true;
            });
            renderGroups();
            updateBatchOperationButtons();
            playSound(confirmSound);
        }
        
        // 取消全选
        function deselectAllGroups() {
            groups.forEach(group => {
                group.selected = false;
            });
            renderGroups();
            updateBatchOperationButtons();
            playSound(cancelSound);
        }
        
        // 删除选中的小组
        function deleteSelectedGroups() {
            const selectedCount = groups.filter(g => g.selected).length;
            if (selectedCount === 0) return;
            
            if (confirm(`确定要删除选中的 ${selectedCount} 个小组吗？`)) {
                groups = groups.filter(g => !g.selected);
                renderGroups();
                updateBatchOperationButtons();
                playSound(removeSound);
            }
        }
        
        // 清空所有小组
        function clearAllGroups() {
            if (groups.length === 0) return;
            
            if (confirm(`确定要清空所有 ${groups.length} 个小组吗？此操作不可恢复！`)) {
                groups = [];
                renderGroups();
                updateBatchOperationButtons();
                playSound(removeSound);
            }
        }
        
        // 更新批量操作按钮状态
        function updateBatchOperationButtons() {
            const hasGroups = groups.length > 0;
            const hasSelected = groups.some(g => g.selected);
            
            // 更新按钮状态
            selectAllBtn.disabled = !hasGroups;
            deselectAllBtn.disabled = !hasGroups || !hasSelected;
            deleteSelectedBtn.disabled = !hasSelected;
            clearAllGroupsBtn.disabled = !hasGroups;
            
            // 更新按钮样式
            if (selectAllBtn.disabled) {
                selectAllBtn.classList.add('opacity-50', 'cursor-not-allowed');
            } else {
                selectAllBtn.classList.remove('opacity-50', 'cursor-not-allowed');
            }
            
            if (deselectAllBtn.disabled) {
                deselectAllBtn.classList.add('opacity-50', 'cursor-not-allowed');
            } else {
                deselectAllBtn.classList.remove('opacity-50', 'cursor-not-allowed');
            }
            
            if (deleteSelectedBtn.disabled) {
                deleteSelectedBtn.classList.add('opacity-50', 'cursor-not-allowed');
            } else {
                deleteSelectedBtn.classList.remove('opacity-50', 'cursor-not-allowed');
            }
            
            if (clearAllGroupsBtn.disabled) {
                clearAllGroupsBtn.classList.add('opacity-50', 'cursor-not-allowed');
            } else {
                clearAllGroupsBtn.classList.remove('opacity-50', 'cursor-not-allowed');
            }
        }
        
        // 加分
        function addScore(groupId) {
            const index = groups.findIndex(g => g.id === groupId);
            if (index !== -1) {
                const step = parseInt(document.getElementById('score-step').value) || 1;
                groups[index].score += step;
                
                // 更新分数显示并添加动画
                const scoreElement = document.querySelector(`.group-card[data-id="${groupId}"] .group-score`);
                if (scoreElement && animationEnabled) {
                    // 重置动画类以重新触发动画
                    scoreElement.classList.remove('score-change-up');
                    void scoreElement.offsetWidth; // 触发重绘
                    scoreElement.classList.add('score-change-up');
                }
                
                scoreElement.textContent = groups[index].score;
                playSound(addSound);
                
                // 分数变化后重新渲染以更新排名
                renderGroups();
            }
        }
        
        // 减分
        function subtractScore(groupId) {
            const index = groups.findIndex(g => g.id === groupId);
            if (index !== -1 && groups[index].score > 0) {
                const step = parseInt(document.getElementById('score-step').value) || 1;
                groups[index].score = Math.max(0, groups[index].score - step);
                
                // 更新分数显示并添加动画
                const scoreElement = document.querySelector(`.group-card[data-id="${groupId}"] .group-score`);
                if (scoreElement && animationEnabled) {
                    // 重置动画类以重新触发动画
                    scoreElement.classList.remove('score-change-down');
                    void scoreElement.offsetWidth; // 触发重绘
                    scoreElement.classList.add('score-change-down');
                }
                
                scoreElement.textContent = groups[index].score;
                playSound(removeSound);
                
                // 分数变化后重新渲染以更新排名
                renderGroups();
            }
        }
        
        // 重置所有分数
        function resetAllScores() {
            if (groups.length === 0) {
                playSound(cancelSound);
                return;
            }
            
            if (confirm('确定要重置所有小组的分数吗？')) {
                groups.forEach(group => {
                    group.score = 0;
                });
                renderGroups();
                playSound(successSound);
            } else {
                playSound(cancelSound);
            }
        }
        
        // 计算排名
        function calculateRanks(groups) {
            // 复制并筛选出分数 > 0 的小组
            const rankedGroups = [...groups].filter(group => group.score > 0);
            
            // 按分数从高到低排序
            rankedGroups.sort((a, b) => b.score - a.score);
            
            // 计算排名（处理并列情况）
            if (rankedGroups.length > 0) {
                let currentRank = 1;
                rankedGroups[0].rank = currentRank;
                
                for (let i = 1; i < rankedGroups.length; i++) {
                    // 如果当前分数与上一个不同，更新排名
                    if (rankedGroups[i].score !== rankedGroups[i - 1].score) {
                        currentRank = i + 1;
                    }
                    rankedGroups[i].rank = currentRank;
                }
            }
            
            // 返回带有排名信息的小组数组
            return rankedGroups;
        }
        
        // 渲染小组卡片 - 重点优化分数显示
        function renderGroups() {
            // 保存当前所有卡片的位置信息，用于动画
            const currentCards = {};
            document.querySelectorAll('.group-card').forEach(card => {
                const id = card.dataset.id;
                currentCards[id] = {
                    element: card,
                    rect: card.getBoundingClientRect()
                };
            });
            
            if (groups.length === 0) {
                groupsContainer.innerHTML = `
                    <div class="col-span-full text-center py-10 text-gray-500 italic">
                        <i class="fa fa-users text-5xl mb-3 opacity-30"></i>
                        <p>点击"添加小组"或"批量添加"来创建小组</p>
                    </div>
                `;
                return;
            }
            
            // 计算排名（只针对分数>0的小组）
            const rankedGroups = calculateRanks(groups);
            
            // 获取所有小组（包括0分小组）并按排名和分数排序
            const allGroups = [...groups].sort((a, b) => {
                // 有排名的小组排在前面
                const aHasRank = rankedGroups.some(g => g.id === a.id);
                const bHasRank = rankedGroups.some(g => g.id === b.id);
                
                if (aHasRank && !bHasRank) return -1;
                if (!aHasRank && bHasRank) return 1;
                
                // 都有排名或都没有排名
                if (aHasRank && bHasRank) {
                    // 按排名排序
                    const aRank = rankedGroups.find(g => g.id === a.id).rank;
                    const bRank = rankedGroups.find(g => g.id === b.id).rank;
                    return aRank - bRank;
                } else {
                    // 都没有排名（0分），按名称排序
                    return a.name.localeCompare(b.name);
                }
            });
            
            // 先创建所有新卡片但不添加到DOM
            const newCards = {};
            allGroups.forEach((group, index) => {
                const groupCard = document.createElement('div');
                // 添加选中状态的样式
                const selectedClass = group.selected ? 'selected pulse-selection' : '';
                groupCard.className = `group-card bg-white rounded-xl shadow-md overflow-hidden transition-all duration-500 hover:shadow-lg transform hover:-translate-y-1 ${selectedClass}`;
                groupCard.dataset.id = group.id;
                
                // 检查是否有排名（分数>0）
                const rankedGroup = rankedGroups.find(g => g.id === group.id);
                const hasRank = !!rankedGroup;
                
                // 排名徽章（只有有排名的小组才显示）
                let rankBadge = '';
                if (hasRank) {
                    const rank = rankedGroup.rank;
                    if (rank === 1) {
                        rankBadge = `<div class="rank-badge-1 absolute top-2 left-2 text-white text-xs font-bold px-3 py-1.5 rounded-full flex items-center z-10">
                            <i class="fa fa-trophy mr-1 text-yellow-800"></i> 第${rank}名
                        </div>`;
                    } else if (rank === 2) {
                        rankBadge = `<div class="rank-badge-2 absolute top-2 left-2 text-gray-800 text-xs font-bold px-3 py-1.5 rounded-full flex items-center z-10">
                            <i class="fa fa-trophy mr-1 text-gray-600"></i> 第${rank}名
                        </div>`;
                    } else if (rank === 3) {
                        rankBadge = `<div class="rank-badge-3 absolute top-2 left-2 text-white text-xs font-bold px-3 py-1.5 rounded-full flex items-center z-10">
                            <i class="fa fa-trophy mr-1 text-amber-900"></i> 第${rank}名
                        </div>`;
                    } else {
                        rankBadge = `<div class="rank-badge-other absolute top-2 left-2 text-white text-xs font-bold px-3 py-1.5 rounded-full flex items-center z-10 transform rotate(1deg)">
                            <i class="fa fa-star mr-1"></i> 第${rank}名
                        </div>`;
                    }
                }
                
                // 优化分数显示：进一步增大分数字号，使用更大的clamp范围
                const scoreClass = group.score > 0 ? 'text-secondary score-highlight font-black' : 'text-gray-400 score-zero';
                
                groupCard.innerHTML = `
                    <!-- 选择框 -->
                    <div class="absolute top-2 right-2 z-20">
                        <label class="cursor-pointer">
                            <input type="checkbox" class="group-selector hidden" ${group.selected ? 'checked' : ''}>
                            <div class="w-5 h-5 rounded border-2 ${group.selected ? 'border-primary bg-primary text-white' : 'border-gray-300'} flex items-center justify-center">
                                ${group.selected ? '<i class="fa fa-check text-xs"></i>' : ''}
                            </div>
                        </label>
                    </div>
                    
                    <div class="relative ${group.color} h-4"></div>
                    ${rankBadge}
                    <div class="p-4 relative flex-1 flex flex-col">
                        <div class="flex justify-between items-start mb-2">
                            <h3 class="group-name font-bold text-lg">${group.name}</h3>
                            <div class="flex gap-1">
                                <button class="edit-group p-1.5 text-gray-500 hover:text-primary rounded-full hover:bg-gray-100 transition-colors" title="编辑小组">
                                    <i class="fa fa-pencil"></i>
                                </button>
                                <button class="delete-group p-1.5 text-gray-500 hover:text-danger rounded-full hover:bg-gray-100 transition-colors" title="删除小组">
                                    <i class="fa fa-trash"></i>
                                </button>
                            </div>
                        </div>
                        <!-- 重点优化：分数字号显著增大，占据卡片主要视觉空间 -->
                        <div class="flex items-center justify-center flex-1 my-1">
                            <span class="group-score text-[clamp(3.5rem,10vw,6rem)] leading-none ${scoreClass}">${group.score}</span>
                            <span class="ml-3 text-gray-500 text-xl font-semibold self-end mb-6">分</span>
                        </div>
                        <div class="flex gap-2 mt-1">
                            <button class="subtract-score flex-1 bg-danger/10 hover:bg-danger/20 text-danger py-3 rounded-lg transition-colors flex items-center justify-center text-lg ${group.score === 0 ? 'opacity-50 cursor-not-allowed' : ''}">
                                <i class="fa fa-minus-circle mr-2"></i> 减分
                            </button>
                            <button class="add-score flex-1 bg-secondary/10 hover:bg-secondary/20 text-secondary py-3 rounded-lg transition-colors flex items-center justify-center text-lg">
                                <i class="fa fa-plus-circle mr-2"></i> 加分
                            </button>
                        </div>
                    </div>
                `;
                
                // 添加事件监听
                const deleteBtn = groupCard.querySelector('.delete-group');
                deleteBtn.addEventListener('click', function(e) {
                    e.stopPropagation();
                    deleteGroup(group.id);
                });
                
                const editBtn = groupCard.querySelector('.edit-group');
                editBtn.addEventListener('click', function(e) {
                    e.stopPropagation();
                    openEditGroupModal(group.id);
                });
                
                const addBtn = groupCard.querySelector('.add-score');
                addBtn.addEventListener('click', function(e) {
                    e.stopPropagation();
                    addScore(group.id);
                });
                
                const subtractBtn = groupCard.querySelector('.subtract-score');
                subtractBtn.addEventListener('click', function(e) {
                    e.stopPropagation();
                    if (group.score > 0) {
                        subtractScore(group.id);
                    }
                });
                
                // 选择框事件
                const selector = groupCard.querySelector('.group-selector').parentElement;
                selector.addEventListener('click', function(e) {
                    e.stopPropagation();
                    toggleGroupSelection(group.id);
                });
                
                // 点击卡片空白处也可以切换选择状态
                groupCard.addEventListener('click', function() {
                    toggleGroupSelection(group.id);
                });
                
                newCards[group.id] = {
                    element: groupCard,
                    index: index
                };
            });
            
            // 清空容器但保留位置信息用于动画
            const tempContainer = document.createElement('div');
            tempContainer.style.display = 'none';
            document.body.appendChild(tempContainer);
            
            // 先将所有现有卡片移动到临时容器
            document.querySelectorAll('.group-card').forEach(card => {
                tempContainer.appendChild(card);
            });
            
            // 清空主容器并添加所有新卡片
            groupsContainer.innerHTML = '';
            allGroups.forEach((group, index) => {
                const newCard = newCards[group.id].element;
                groupsContainer.appendChild(newCard);
                
                // 如果是新卡片，添加进入动画
                if (!currentCards[group.id] && animationEnabled) {
                    newCard.style.opacity = '0';
                    newCard.style.transform = 'translateY(20px)';
                    setTimeout(() => {
                        newCard.style.opacity = '1';
                        newCard.style.transform = 'translateY(0)';
                    }, 50);
                }
            });
            
            // 对现有卡片应用位置过渡动画
            if (animationEnabled) {
                allGroups.forEach((group) => {
                    const existingCard = currentCards[group.id];
                    const newCard = newCards[group.id];
                    
                    if (existingCard && newCard) {
                        const newRect = newCard.element.getBoundingClientRect();
                        const oldRect = existingCard.rect;
                        
                        // 计算位置差异
                        const diffX = oldRect.left - newRect.left;
                        const diffY = oldRect.top - newRect.top;
                        
                        // 应用初始变换使卡片看起来在原来的位置
                        newCard.element.style.transform = `translate(${diffX}px, ${diffY}px)`;
                        newCard.element.style.opacity = '1';
                        
                        // 触发重绘
                        void newCard.element.offsetWidth;
                        
                        // 应用过渡到新位置
                        setTimeout(() => {
                            newCard.element.style.transform = 'translate(0, 0)';
                        }, 50);
                    }
                });
            }
            
            // 移除临时容器
            document.body.removeChild(tempContainer);
        }
        
        // 打开保存班级模态框
        function openSaveClassModal() {
            if (groups.length === 0) {
                alert('请先添加小组再保存班级');
                playSound(cancelSound);
                return;
            }
            document.getElementById('class-name').value = '';
            saveClassModal.classList.remove('hidden');
            document.getElementById('class-name').focus();
            playSound(selectSound);
        }
        
        // 关闭保存班级模态框
        function closeSaveClassModal() {
            saveClassModal.classList.add('hidden');
        }
        
        // 保存当前班级
        function saveCurrentClass() {
            const className = document.getElementById('class-name').value.trim();
            if (!className) {
                alert('请输入班级名称');
                playSound(cancelSound);
                return;
            }
            
            // 获取已保存的班级
            let savedClasses = JSON.parse(localStorage.getItem('savedClasses') || '[]');
            
            // 检查是否已存在同名班级
            const existingIndex = savedClasses.findIndex(c => c.name === className);
            if (existingIndex !== -1) {
                if (!confirm(`"${className}" 已存在，是否覆盖？`)) {
                    playSound(cancelSound);
                    return;
                }
                savedClasses.splice(existingIndex, 1);
            }
            
            // 创建新班级数据
            const classData = {
                id: Date.now().toString(),
                name: className,
                groups: groups,
                savedAt: new Date().toISOString()
            };
            
            // 保存到本地存储
            savedClasses.push(classData);
            localStorage.setItem('savedClasses', JSON.stringify(savedClasses));
            
            // 更新班级列表
            loadSavedClasses();
            
            closeSaveClassModal();
            playSound(successSound);
            alert(`班级 "${className}" 已保存成功`);
        }
        
        // 加载已保存的班级
        function loadSavedClasses() {
            const savedClasses = JSON.parse(localStorage.getItem('savedClasses') || '[]');
            
            if (savedClasses.length === 0) {
                savedClassesContainer.innerHTML = '<div class="col-span-full text-gray-500 italic text-center py-4">暂无保存的班级数据</div>';
                return;
            }
            
            // 按保存时间排序（最新的在前）
            savedClasses.sort((a, b) => new Date(b.savedAt) - new Date(a.savedAt));
            
            savedClassesContainer.innerHTML = '';
            
            savedClasses.forEach(classData => {
                const classCard = document.createElement('div');
                classCard.className = 'bg-white border border-gray-200 rounded-lg p-3 shadow-sm hover:shadow transition-all';
                
                // 格式化日期
                const savedDate = new Date(classData.savedAt);
                const formattedDate = `${savedDate.getFullYear()}-${(savedDate.getMonth() + 1).toString().padStart(2, '0')}-${savedDate.getDate().toString().padStart(2, '0')}`;
                
                classCard.innerHTML = `
                    <div class="flex justify-between items-start">
                        <h4 class="font-bold">${classData.name}</h4>
                        <div class="flex gap-1">
                            <button class="load-class p-1 text-primary hover:bg-primary/10 rounded" title="加载班级">
                                <i class="fa fa-download"></i>
                            </button>
                            <button class="delete-class p-1 text-gray-500 hover:text-danger hover:bg-danger/10 rounded" title="删除班级">
                                <i class="fa fa-trash"></i>
                            </button>
                        </div>
                    </div>
                    <p class="text-sm text-gray-500 mt-1">${classData.groups.length} 个小组 · 保存于 ${formattedDate}</p>
                `;
                
                savedClassesContainer.appendChild(classCard);
                
                // 添加事件监听
                classCard.querySelector('.load-class').addEventListener('click', () => {
                    loadClassData(classData.id);
                    playSound(confirmSound);
                });
                
                classCard.querySelector('.delete-class').addEventListener('click', () => {
                    deleteClassData(classData.id, classData.name);
                });
            });
        }
        
        // 加载班级数据
        function loadClassData(classId) {
            const savedClasses = JSON.parse(localStorage.getItem('savedClasses') || '[]');
            const classData = savedClasses.find(c => c.id === classId);
            
            if (classData) {
                groups = [...classData.groups];
                // 确保加载后ID计数器正确设置
                groupIdCounter = groups.length > 0 
                    ? Math.max(...groups.map(g => parseInt(g.id.split('-')[1], 36))) + 1 
                    : 0;
                renderGroups();
                toggleClassSelector();
                updateBatchOperationButtons();
                alert(`已加载班级: ${classData.name}`);
            }
        }
        
        // 删除班级数据
        function deleteClassData(classId, className) {
            if (confirm(`确定要删除班级 "${className}" 吗？`)) {
                let savedClasses = JSON.parse(localStorage.getItem('savedClasses') || '[]');
                savedClasses = savedClasses.filter(c => c.id !== classId);
                localStorage.setItem('savedClasses', JSON.stringify(savedClasses));
                loadSavedClasses();
                playSound(removeSound);
            } else {
                playSound(cancelSound);
            }
        }
        
        // 切换班级选择器显示
        function toggleClassSelector() {
            classSelector.classList.toggle('hidden');
            playSound(selectSound);
        }
        
        // 打开设置模态框
        function openSettingsModal() {
            settingsModal.classList.remove('hidden');
            playSound(selectSound);
        }
        
        // 关闭设置模态框（点击外部时）
        settingsModal.addEventListener('click', (e) => {
            if (e.target === settingsModal) {
                settingsModal.classList.add('hidden');
                playSound(cancelSound);
            }
        });
        
        // 清除所有保存数据
        function clearAllData() {
            if (confirm('确定要清除所有保存的班级数据吗？此操作不可恢复！')) {
                localStorage.removeItem('savedClasses');
                loadSavedClasses();
                playSound(removeSound);
                alert('所有保存的数据已清除');
            } else {
                playSound(cancelSound);
            }
        }
        
        // 点击模态框外部关闭
        [groupModal, batchModal, saveClassModal].forEach(modal => {
            modal.addEventListener('click', (e) => {
                if (e.target === modal) {
                    modal.classList.add('hidden');
                    playSound(cancelSound);
                }
            });
        });
        
        // 阻止模态框内部点击事件冒泡
        document.querySelectorAll('#group-modal > div, #batch-modal > div, #save-class-modal > div, #settings-modal > div').forEach(modalContent => {
            modalContent.addEventListener('click', (e) => {
                e.stopPropagation();
            });
        });
        
        // 初始化应用
        document.addEventListener('DOMContentLoaded', init);
    </script>
</body>
</html>
